#include "pipe_elements.h"
#include <map>
#include <iostream>
using namespace std;

void BTB::insert(int addr, int taddr )
{
    if(list.size()==6)
        deleteatend();
    list.push(addr);
    mBTB *newentry=new mBTB(addr, taddr);
    newentry->predict=0;
    BTBl[addr]=*newentry;
}
void BTB::deleteatend()
{
    int temp=list.front();
    list.pop();
    BTBl.erase(temp);

}

int BTB::getaddr(int xaddr)
{
    mBTB temp=BTBl[xaddr];
    if(temp.predict)
        return temp.taddr;
    else
        return xaddr+4;
}
int BTB::member(int xaddr)
{
    return BTBl.count(xaddr);
}
int BTB::settaken(int xaddr)//returns 1 if it was changed
{
    BTBl[xaddr].predict=1;
    
}
int BTB::taken(int xaddr)//returns 1 if it was changed
{
    mBTB temp=BTBl[xaddr];
    return temp.predict;
}
int BTB::nottaken(int xaddr)//returns 1 if it was changed
{
    BTBl[xaddr].predict=0;
    
}
int BTB::setnottaken(int xaddr)//returns 1 if it was changed
{
    mBTB temp=BTBl[xaddr];
    if(!temp.predict)
        return 0;
    if(temp.predict)
        temp.predict=0;
    return 1;
}
mBTB::mBTB(int a, int b)
{

    iaddr=a;
    taddr=b;

}
void BTB::fprint()
{
    map<int,mBTB>::iterator i;
    cout<<"BTB:"<<endl;
    int ii=1;

    for(i=BTBl.begin();i!=BTBl.end();i++)
    {
        cout<<"[Entry "<<ii<<"]:<"<<(*i).second.iaddr<<","<<(*i).second.taddr<<","<<(*i).second.predict<<">"<<endl;
        ii++;
    }
    cout<<endl;
}